package com.push.core;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.push.common.IStartMsgPlus;
import com.push.common.StartMsgPushConstant;
import com.push.common.entity.StartPlusTemplate;
import com.push.core.service.StartPlusTemplateService;
import com.start.common.entity.StartBaseUser;
import com.start.common.std.StartBaseSingleton;
import com.start.common.std.StartSingletonFactory;
import com.start.common.tools.SpringContextTools;
import com.start.common.tools.StartUserTools;
import com.start.common.user.StartUserInfoLoadService;
import com.start.security.StartUserContextManage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;


@Slf4j
public class StartPushManage extends StartBaseSingleton<StartPushManage> implements StartMsgPushConstant {
    private static StartPushManage instance;

    private static Map<String, IStartMsgPlus> startMsgPlusMap;

    private StartPlusTemplateService startPlusTemplateService;

    public static StartPushManage getInstance() {
        return StartSingletonFactory.get(StartPushManage.class);
    }

    /**
     * 调用初始化函数
     */
    @Override
    public void init() {
        startMsgPlusMap = new HashMap<>();
        startPlusTemplateService = SpringContextTools.getBean(StartPlusTemplateService.class);
        Map<String, IStartMsgPlus> beanMap = SpringContextTools.getBeans(IStartMsgPlus.class, false);
        if (beanMap == null || beanMap.isEmpty()) return;
        Collection<IStartMsgPlus> values = beanMap.values();
        for (IStartMsgPlus plus : values) {
            if (StringUtils.isAllBlank(plus.getMsgPlusKey())) {
                log.warn("推送器无效请设置推送器唯一key:" + plus.getClass().getName());
                continue;
            }
            if (startMsgPlusMap.containsKey(plus.getMsgPlusKey())) {
                log.warn("已存在相同唯一键的推送器:" + plus.getMsgPlusKey());
                log.warn("推送器:" + startMsgPlusMap.get(plus.getMsgPlusKey()).getClass().getName());
                log.warn("推送器:" + plus.getClass().getName());
                continue;
            }
            startMsgPlusMap.put(plus.getMsgPlusKey(), plus);
        }


    }

    /**
     * 批量推送消息
     *
     * @param templateCode   消息模板编码
     * @param pushUserKey    推送人信息
     * @param receiveUserKey 接收人key （格式为 startUserType:userId）
     * @param data           推送数据
     */
    public void push(String templateCode, String pushUserKey, String receiveUserKey, JSONObject data) {
        List<StartPlusTemplate> plusTemplates = getPlusTemplates(templateCode);
        if (plusTemplates.isEmpty()) {
            return;
        }
        JSONObject paramsContext = new JSONObject();
        JSONObject puContext = createUserContext(pushUserKey);
        puContext.put(PUSH_D_KEY, data);
        paramsContext.put(PUSH_P_KEY, puContext);
        JSONObject ruContext = createUserContext(receiveUserKey);
        puContext.put(PUSH_D_KEY, data);
        paramsContext.put(PUSH_R_KEY, ruContext);
        for (StartPlusTemplate template : plusTemplates) {
            if (!startMsgPlusMap.containsKey(template.getPlatformType())) {
                continue;
            }
            startMsgPlusMap.get(templateCode).plusMsg(template, paramsContext);
        }
    }

    /**
     * 批量推送消息
     *
     * @param templateCode    消息模板编码
     * @param pushUserKey     推送人信息
     * @param receiveUserKeys 接收人keys （格式为 startUserType:userId）
     * @param data            推送数据
     */
    public void batchPush(String templateCode, String pushUserKey, Collection<String> receiveUserKeys, JSONObject data) {
        List<StartPlusTemplate> plusTemplates = getPlusTemplates(templateCode);
        if (plusTemplates.isEmpty()) {
            return;
        }
        JSONObject paramsContext = new JSONObject();
        JSONObject puContext = createUserContext(pushUserKey);
        puContext.put(PUSH_D_KEY, data);
        paramsContext.put(PUSH_P_KEY, puContext);
        JSONArray userContext = createUserContext(receiveUserKeys);
        paramsContext.put(PUSH_R_KEY, userContext);
        for (StartPlusTemplate template : plusTemplates) {
            if (!startMsgPlusMap.containsKey(template.getPlatformType())) {
                continue;
            }
            startMsgPlusMap.get(templateCode).batchPush(template, paramsContext);
        }
    }

    /**
     * 创建用户上下文
     *
     * @param startUserKey
     * @return
     */
    private JSONObject createUserContext(String startUserKey) {
        String[] userData = startUserKey.split(":");
        StartBaseUser pushUserInfo = StartUserInfoLoadService.getInstance().getUserById(userData[0], userData[1]);
        JSONObject userContext = StartUserContextManage.getInstance().getUserContext(userData[0], userData[1]);
        JSONObject pu = new JSONObject();
        pu.put(PUSH_I_KEY, pushUserInfo);
        pu.put(PUSH_C_KEY, userContext);
        return pu;
    }

    private static JSONArray createUserContext(Collection<String> startUserKeys) {
        JSONArray userContextArray = new JSONArray();
        if (startUserKeys.isEmpty()) {
            return new JSONArray();
        }
        Map<String, List<String>> userKeyMap = StartUserTools.getUserKeyMap(startUserKeys);
        for (String key : userKeyMap.keySet()) {
            List<String> userIds = userKeyMap.get(key);
            for (String userId : userIds) {
                StartBaseUser pushUserInfo = StartUserInfoLoadService.getInstance().getUserById(key, userId);
                JSONObject userContext = StartUserContextManage.getInstance().getUserContext(key, userId);
                JSONObject pu = new JSONObject();
                pu.put(PUSH_I_KEY, pushUserInfo);
                pu.put(PUSH_C_KEY, userContext);
                userContextArray.add(pu);
            }

        }
        return userContextArray;
    }

    private List<StartPlusTemplate> getPlusTemplates(String templateCode) {
        LambdaQueryWrapper<StartPlusTemplate> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StartPlusTemplate::getTemplateCode, templateCode);
        lambdaQueryWrapper.eq(StartPlusTemplate::getIsEnable, 1);
        return startPlusTemplateService.list(lambdaQueryWrapper);
    }
}
